#ifndef BP_H
#define BP_H

#include "data.h"

#include <list>
#include <boost/shared_array.hpp>
#include <boost/shared_ptr.hpp>

namespace BP {

// useful array types
typedef boost::multi_array<double, 2> Array2d;
typedef boost::multi_array<double, 3> Array3d;
typedef boost::multi_array<double, 4> Array4d;

typedef std::list<std::pair<int,size_t> > Labelling;
typedef boost::shared_ptr<Labelling> LabellingPtr;
    
double 
log_sum(double a, 
        double b);

LabellingPtr
viterbi(EventPtr v, 
		Array3d&, Array4d&,
		bool print=false,
		bool generic_cliques=false);

LabellingPtr
max_cost_viterbi(EventPtr v, Array3d &nodes, Array4d &cliques, bool print,
	double (*cost_func)(int,double,int,double));

void 
forward_backward(EventPtr v, 
		Array3d&, Array4d&,
		Array2d &forward, Array2d &backward, 
		bool print=false);

void 
calculate_dot_products(EventPtr e, double* weights, 
	Array3d &nodes, Array4d &cliques, bool generic_cliques=false);

void 
calculate_dot_products(EventPtr e, boost::shared_array<double> weights, 
	Array3d &nodes, Array4d &cliques, bool generic_cliques=false);

//std::pair<LatticePtr,boost::shared_ptr<std::vector<int> > >
//prob_lattice(EventPtr e, 
//        boost::shared_array<double> weights);

} // namespace BP

#endif // BP_H
